﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Farigola.Engine.SystemData.Entity.Type;

namespace Farigola.Engine.SystemData.Entity.inst
{
    /// <summary>
    /// Base class of instance class (std and anonym).
    /// </summary>
    public abstract class EntInstClassBase : EntInstDataBase
    {
        /**
         * The type class of the instance class.
         */
        protected EntTypeClassBase _entTypeClassBase;

        /**
         * list of data member, based on the typeClass.
         */
        protected List<EntInstBase> _listDataMember = new List<EntInstBase>();

        /**
         * used for data member instance, because there are no link to the type data member.
         * (code/key) Id typeDatamember -> (value) Id instDataMember 
         */
        //protected Map<EntityId, EntityId> _dictTypeToInst = new Hashtable<EntityId, EntityId>();


        //=====================================================================
        // Constructors.

        //---------------------------------------------------------------------
        /**
         * constructor.
         * 
         * @param systOrUser
         * @param id
         * @param name
         */
        public EntInstClassBase(EntityDef.TypeSystOrUser systOrUser, EntTypeClassBase entTypeClassBase, EntityId id, String name)
            : base(systOrUser, id, name)
        {            
            _entTypeClassBase = entTypeClassBase;
        }

        //---------------------------------------------------------------------
        /**
         * constructor.
         * 
         * @param id
         * @param name
         */
        public EntInstClassBase(EntTypeClassBase entTypeClassBase, EntityId id, String name)
            : base(id, name)
        {            
            _entTypeClassBase = entTypeClassBase;
        }

        //=====================================================================
        // get/set methods.

        //---------------------------------------------------------------------
        public EntTypeClassBase getEntTypeClassBase()
        {
            return _entTypeClassBase;
        }

        //---------------------------------------------------------------------
        public List<EntInstBase> getListDataMember()
        {
            return _listDataMember;
        }

        //=====================================================================
        // Find methods.

        //---------------------------------------------------------------------
        /**
         * Find a data member instance, by the name.
         * @param name
         * @return
         */
        public EntInstBase FindEntInstDataMemberByName(String name)
        {
            if (name == null)
                return null;

            foreach(EntInstBase ent in _listDataMember)
            {
        	    if(name.Equals(ent.GetName(),StringComparison.OrdinalIgnoreCase))
        		    return ent;
            }
        
            return null;
        }

        //---------------------------------------------------------------------
        /**
         * Find a data member instance, by the id.
         * @param name
         * @return
         */
        public EntInstBase findEntInstDataMemberById(EntityId id)
        {
            if (id == null)
                return null;

            foreach(EntInstBase ent in _listDataMember)
            {
        	    if(id.IdAreEquals(ent.GetId()))
        		    return ent;
            }
        
            return null;
        }

        //    //---------------------------------------------------------------------
        //    /**
        //     * find the type class data member id, by the id of the data member instance.
        //     * 
        //     * @param id
        //     * @return
        //     */
        //    public EntityId findTypeClassDataMemberIdByEntInstId(EntityId id)
        //    {
        //    	if(id==null)
        //    		return null;
        //    	
        //    	for(Map.Entry<EntityId, EntityId> e : _dictTypeToInst.entrySet()){
        //    		if(id.idEquals(e.getValue()))
        //    			return e.getKey();
        //    	}
        //
        //        return null;
        //    }

        //=====================================================================
        // Some protected methods.

        //    //---------------------------------------------------------------------
        //    /**
        //     * Find the key by the bvalue in the internal map.
        //     * key= typeClassDataMember.Id, value= instanceDataMember.Id
        //     * 
        //     * @param instDataMemberId
        //     * @return
        //     */
        //    protected EntityId dictFindKeyByValue(EntityId instDataMemberId)
        //    {
        //    	if(instDataMemberId==null)
        //    		return null;
        //
        //        // Loop over pairs with foreach
        //    	for(Map.Entry<EntityId, EntityId> e : _dictTypeToInst.entrySet()){
        //    		if(instDataMemberId.idEquals(e.getValue()))
        //    			return e.getKey();
        //    	}
        //
        //        return null;
        //    }

        //    //=====================================================================
        //    // add/remove data member methods.
        //
        //    //---------------------------------------------------------------------
        //    /**
        //     * Add a new data member to the instance class.
        //     * Data members of an instance class are build by the factory when the instance class is created.
        //     * 
        //     * @param instanceDataMember
        //     * @param typeDataMember
        //     * @return
        //     */
        //    public boolean addEntInstDataMember(EntInstBase instanceDataMember, EntTypeClassDataMember typeDataMember)
        //    {
        //        // check if not already present
        //        if(_listDataMember.contains(instanceDataMember))
        //            return false;
        //
        //        // check if the newName is not already used
        //        // todo:
        //
        //  		_listDataMember.add(instanceDataMember);

        //        // add an entry in the dict, for inst, to keep a link to the typeClassDataMember
        //        _dictTypeToInst.put(typeDataMember.getId(), instanceDataMember.getId());
        //        
        //        return true;
        //    }

        //    //---------------------------------------------------------------------
        //    /**
        //     * remove the inst data member from the class.
        //     * @param instDataMember
        //     * @return
        //     */
        //    public boolean removeEntInstClassDataMember(EntInstBase instDataMember)
        //    {
        //        if (instDataMember == null)
        //            return false;
        //
        //        if (!_listDataMember.contains(instDataMember))
        //            return false;
        //
        //        _listDataMember.remove(instDataMember);
        //
        //        // remove from the dict of the instClass!!
        //        if (!_dictTypeToInst.containsValue(instDataMember.getId()))
        //            return false;
        //
        //        EntityId id = dictFindKeyByValue(instDataMember.getId());
        //        if (id==null)
        //            return false;
        //
        //        _dictTypeToInst.remove(id);
        //        return true;
        //    }
    }
}
